import java.io.File;
import java.io.FileNotFoundException;

/**
 * Main class instantiates model, view and controller for the game and gets them
 * going. Functionally the 'Go' button for the program.
 *
 * @author Sam Snyder
 *
 */
public final class Jotto {

	/**
	 * Display this JFrame.
	 * 
	 * @param args
	 *            Optional parameter defines the maximum number of guesses this
	 *            game. <br />
	 *            Optional parameter defines a filename to load a dictionary
	 *            from. <br />
	 *            Accepts parameters in any order.
	 * 
	 */
	public static void main(String[] args) {
		
		// Set default number of turns and default dictionary file
		final int defaultmaxguesses = 20;
		String dictionary = "dictionary.txt";
		
		// Parse the arguments to see if the user specified guesses / dictionary
		int maxguesses = parseArgs(args, defaultmaxguesses, dictionary);

		// Start the model, view and controller
		
		try {
			GameModel model = new JottoModel(maxguesses, dictionary);
			GameView view = new JottoView(maxguesses);
			@SuppressWarnings("unused")
			GameController controller = new JottoController(view, model);
		} catch (FileNotFoundException e) {
			System.err.println(
					"Failed to load dictionary file: unrecoverable error, exiting.");
		}
	}

	/**
	 * Utility class. No instantiation.
	 */
	private Jotto() { }

	/**
	 * Parses the arguments in the String[] args to see if a valid number of
	 * guesses and/or dictionary file is specified. If one or both is, in either
	 * order, then use them. If neither are or if the given values are unusable
	 * substitute defaults. Exit the program in failure if neither the specified
	 * nor default dictionary can be read.
	 * 
	 * 
	 * @param args
	 *            the arguments to be parsed
	 * @param maxguesses Takes in a default number of guesses.
	 * @param dictionary
	 *            Takes in a default or fall-back file name, produces either
	 *            that same filename or the args-specifed one.
	 * @return the number of guesses specified in the args, fitted to 2 <=
	 *         guesses <= 27 or the default 20 guesses.
	 */
	private static int parseArgs(String[] args, int maxguesses, String dictionary) {
		
		// Define the acceptable range for the max number of guesses to fall within
		final int absMaxGuesses = 27;
		final int absMinGuesses = 2;
		
		String defaultdictionary = dictionary;
		File dictionarychecker;

		// If there's one argument figure out if it's numerical or a file name.
		if (args.length == 1) {
			if (args[0].matches("^[0-9]+$")) {
				maxguesses = Integer.parseInt(args[0]);
			} else {
				dictionary = args[0];
			}
		} else if (args.length >= 2) {
			// Two arguments, figure out which is which
			if (args[0].matches("^[0-9]+$")) {
				// First argument is a number
				maxguesses = Integer.parseInt(args[0]);
				dictionary = args[1];
			} else if (args[1].matches("^[0-9]+$")) {
				// Second argument is a number
				maxguesses = Integer.parseInt(args[1]);
				dictionary = args[0];
			} else {
				// Neither are numbers - assume the first is the filename
				// And that the rest is garbage
				dictionary = args[0];
			}
		}
		
		// Ensure that the number is in range
		if (maxguesses > absMaxGuesses) {
			maxguesses = absMaxGuesses;
		} else if (maxguesses < absMinGuesses) {
			maxguesses = absMinGuesses;
		}
		
		// Ensure that the file can be read
		dictionarychecker = new File(dictionary);
		if (!(dictionarychecker.exists() && dictionarychecker.canRead())) {
			dictionarychecker = new File(defaultdictionary);
			dictionary = defaultdictionary;
			// If the supplied dictionary is invalid try the default
			if (!(dictionarychecker.exists() && dictionarychecker.canRead())) {
				System.err.println("Failed to load a valid dictionary file, exiting.");
				System.exit(0);
			}
		}
		return maxguesses;
	}
}
